package com.lifeverse.service;

import com.lifeverse.entity.HealthCheck;
import com.lifeverse.entity.ServiceDiscovery;
import com.lifeverse.entity.SystemAlert;
import com.lifeverse.entity.enums.AlertSeverity;
import com.lifeverse.entity.enums.HealthStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 故障诊断服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DiagnosticService {

    private final AlertService alertService;
    private final HealthCheckService healthCheckService;
    private final ServiceDiscoveryService serviceDiscoveryService;

    /**
     * 执行系统诊断
     */
    public DiagnosticReport performSystemDiagnosis() {
        log.info("开始执行系统诊断");
        
        DiagnosticReport report = new DiagnosticReport();
        report.setDiagnosisTime(LocalDateTime.now());
        
        // 诊断告警系统
        DiagnosticResult alertDiagnosis = diagnoseAlertSystem();
        report.addResult("alert_system", alertDiagnosis);
        
        // 诊断健康检查系统
        DiagnosticResult healthDiagnosis = diagnoseHealthCheckSystem();
        report.addResult("health_check_system", healthDiagnosis);
        
        // 诊断服务发现系统
        DiagnosticResult serviceDiagnosis = diagnoseServiceDiscoverySystem();
        report.addResult("service_discovery_system", serviceDiagnosis);
        
        // 诊断系统性能
        DiagnosticResult performanceDiagnosis = diagnoseSystemPerformance();
        report.addResult("system_performance", performanceDiagnosis);
        
        // 生成整体健康评分
        report.setOverallHealthScore(calculateOverallHealthScore(report));
        
        log.info("系统诊断完成，整体健康评分: {}", report.getOverallHealthScore());
        
        return report;
    }

    /**
     * 诊断告警系统
     */
    private DiagnosticResult diagnoseAlertSystem() {
        DiagnosticResult result = new DiagnosticResult();
        result.setComponentName("告警系统");
        
        try {
            // 检查活跃告警数量
            List<SystemAlert> activeAlerts = alertService.getActiveAlerts();
            result.addMetric("active_alerts_count", activeAlerts.size());
            
            // 检查高优先级告警
            List<SystemAlert> highPriorityAlerts = alertService.getHighPriorityActiveAlerts();
            result.addMetric("high_priority_alerts_count", highPriorityAlerts.size());
            
            // 检查长时间未解决的告警
            List<SystemAlert> longRunningAlerts = alertService.getLongRunningAlerts(24);
            result.addMetric("long_running_alerts_count", longRunningAlerts.size());
            
            // 分析告警趋势
            Map<String, Object> alertStats = alertService.getAlertStatistics();
            result.addMetric("alert_statistics", alertStats);
            
            // 评估告警系统健康状态
            if (highPriorityAlerts.size() > 10) {
                result.setStatus(HealthStatus.CRITICAL);
                result.addIssue("高优先级告警过多: " + highPriorityAlerts.size());
                result.addRecommendation("立即处理高优先级告警，检查系统稳定性");
            } else if (activeAlerts.size() > 50) {
                result.setStatus(HealthStatus.WARNING);
                result.addIssue("活跃告警较多: " + activeAlerts.size());
                result.addRecommendation("检查告警规则配置，处理积压告警");
            } else if (longRunningAlerts.size() > 5) {
                result.setStatus(HealthStatus.WARNING);
                result.addIssue("长时间未解决告警: " + longRunningAlerts.size());
                result.addRecommendation("处理长时间未解决的告警");
            } else {
                result.setStatus(HealthStatus.HEALTHY);
                result.addRecommendation("告警系统运行正常");
            }
            
        } catch (Exception e) {
            result.setStatus(HealthStatus.DOWN);
            result.addIssue("告警系统诊断失败: " + e.getMessage());
            result.addRecommendation("检查告警系统配置和数据库连接");
            log.error("告警系统诊断失败", e);
        }
        
        return result;
    }

    /**
     * 诊断健康检查系统
     */
    private DiagnosticResult diagnoseHealthCheckSystem() {
        DiagnosticResult result = new DiagnosticResult();
        result.setComponentName("健康检查系统");
        
        try {
            // 检查不健康的服务
            List<HealthCheck> unhealthyServices = healthCheckService.getUnhealthyServices();
            result.addMetric("unhealthy_services_count", unhealthyServices.size());
            
            // 获取健康检查统计
            Map<String, Object> healthStats = healthCheckService.getHealthStatistics();
            result.addMetric("health_statistics", healthStats);
            
            // 分析服务可用性
            @SuppressWarnings("unchecked")
            Map<String, Double> availability = (Map<String, Double>) healthStats.get("serviceAvailability");
            if (availability != null) {
                double avgAvailability = availability.values().stream()
                        .mapToDouble(Double::doubleValue)
                        .average()
                        .orElse(0.0);
                result.addMetric("average_availability", avgAvailability);
                
                // 找出可用性低的服务
                List<String> lowAvailabilityServices = availability.entrySet().stream()
                        .filter(entry -> entry.getValue() < 95.0)
                        .map(Map.Entry::getKey)
                        .collect(Collectors.toList());
                
                if (!lowAvailabilityServices.isEmpty()) {
                    result.addIssue("低可用性服务: " + String.join(", ", lowAvailabilityServices));
                    result.addRecommendation("检查低可用性服务的健康状况");
                }
            }
            
            // 评估健康检查系统状态
            if (unhealthyServices.size() > 10) {
                result.setStatus(HealthStatus.CRITICAL);
                result.addIssue("不健康服务过多: " + unhealthyServices.size());
                result.addRecommendation("立即检查不健康的服务");
            } else if (unhealthyServices.size() > 3) {
                result.setStatus(HealthStatus.WARNING);
                result.addIssue("存在不健康服务: " + unhealthyServices.size());
                result.addRecommendation("关注不健康服务的恢复情况");
            } else {
                result.setStatus(HealthStatus.HEALTHY);
                result.addRecommendation("健康检查系统运行正常");
            }
            
        } catch (Exception e) {
            result.setStatus(HealthStatus.DOWN);
            result.addIssue("健康检查系统诊断失败: " + e.getMessage());
            result.addRecommendation("检查健康检查系统配置");
            log.error("健康检查系统诊断失败", e);
        }
        
        return result;
    }

    /**
     * 诊断服务发现系统
     */
    private DiagnosticResult diagnoseServiceDiscoverySystem() {
        DiagnosticResult result = new DiagnosticResult();
        result.setComponentName("服务发现系统");
        
        try {
            // 检查可用服务
            List<ServiceDiscovery> availableServices = serviceDiscoveryService.getAllAvailableServices();
            result.addMetric("available_services_count", availableServices.size());
            
            // 获取服务统计
            Map<String, Object> serviceStats = serviceDiscoveryService.getServiceStatistics();
            result.addMetric("service_statistics", serviceStats);
            
            // 分析服务分布
            @SuppressWarnings("unchecked")
            Map<String, Long> instanceCounts = (Map<String, Long>) serviceStats.get("instanceCounts");
            if (instanceCounts != null) {
                // 找出单点故障风险的服务（只有一个实例）
                List<String> singleInstanceServices = instanceCounts.entrySet().stream()
                        .filter(entry -> entry.getValue() == 1)
                        .map(Map.Entry::getKey)
                        .collect(Collectors.toList());
                
                if (!singleInstanceServices.isEmpty()) {
                    result.addIssue("单点故障风险服务: " + String.join(", ", singleInstanceServices));
                    result.addRecommendation("为单实例服务增加冗余实例");
                }
                
                result.addMetric("single_instance_services_count", singleInstanceServices.size());
            }
            
            // 评估服务发现系统状态
            if (availableServices.isEmpty()) {
                result.setStatus(HealthStatus.CRITICAL);
                result.addIssue("没有可用的服务实例");
                result.addRecommendation("检查服务注册和心跳机制");
            } else if (availableServices.size() < 5) {
                result.setStatus(HealthStatus.WARNING);
                result.addIssue("可用服务实例较少: " + availableServices.size());
                result.addRecommendation("检查服务实例的健康状况");
            } else {
                result.setStatus(HealthStatus.HEALTHY);
                result.addRecommendation("服务发现系统运行正常");
            }
            
        } catch (Exception e) {
            result.setStatus(HealthStatus.DOWN);
            result.addIssue("服务发现系统诊断失败: " + e.getMessage());
            result.addRecommendation("检查服务发现系统配置");
            log.error("服务发现系统诊断失败", e);
        }
        
        return result;
    }

    /**
     * 诊断系统性能
     */
    private DiagnosticResult diagnoseSystemPerformance() {
        DiagnosticResult result = new DiagnosticResult();
        result.setComponentName("系统性能");
        
        try {
            // JVM内存使用情况
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long usedMemory = totalMemory - freeMemory;
            long maxMemory = runtime.maxMemory();
            
            double memoryUsagePercent = (double) usedMemory / maxMemory * 100;
            result.addMetric("memory_usage_percent", memoryUsagePercent);
            result.addMetric("used_memory_mb", usedMemory / 1024 / 1024);
            result.addMetric("max_memory_mb", maxMemory / 1024 / 1024);
            
            // CPU使用情况
            double cpuUsage = ((com.sun.management.OperatingSystemMXBean) 
                    java.lang.management.ManagementFactory.getOperatingSystemMXBean())
                    .getProcessCpuLoad() * 100;
            result.addMetric("cpu_usage_percent", cpuUsage);
            
            // 线程数
            int threadCount = Thread.activeCount();
            result.addMetric("thread_count", threadCount);
            
            // 系统负载
            double systemLoad = java.lang.management.ManagementFactory.getOperatingSystemMXBean()
                    .getSystemLoadAverage();
            if (systemLoad >= 0) {
                result.addMetric("system_load", systemLoad);
            }
            
            // 评估系统性能状态
            List<String> issues = new ArrayList<>();
            List<String> recommendations = new ArrayList<>();
            
            if (memoryUsagePercent > 90) {
                issues.add("内存使用率过高: " + String.format("%.1f%%", memoryUsagePercent));
                recommendations.add("增加JVM堆内存或优化内存使用");
            } else if (memoryUsagePercent > 80) {
                issues.add("内存使用率较高: " + String.format("%.1f%%", memoryUsagePercent));
                recommendations.add("监控内存使用情况，考虑优化");
            }
            
            if (cpuUsage > 80) {
                issues.add("CPU使用率过高: " + String.format("%.1f%%", cpuUsage));
                recommendations.add("检查CPU密集型任务，考虑优化或扩容");
            } else if (cpuUsage > 60) {
                issues.add("CPU使用率较高: " + String.format("%.1f%%", cpuUsage));
                recommendations.add("监控CPU使用情况");
            }
            
            if (threadCount > 1000) {
                issues.add("线程数过多: " + threadCount);
                recommendations.add("检查线程池配置和线程泄漏");
            }
            
            // 设置状态
            if (!issues.isEmpty() && (memoryUsagePercent > 90 || cpuUsage > 80)) {
                result.setStatus(HealthStatus.CRITICAL);
            } else if (!issues.isEmpty()) {
                result.setStatus(HealthStatus.WARNING);
            } else {
                result.setStatus(HealthStatus.HEALTHY);
                recommendations.add("系统性能正常");
            }
            
            result.setIssues(issues);
            result.setRecommendations(recommendations);
            
        } catch (Exception e) {
            result.setStatus(HealthStatus.DOWN);
            result.addIssue("系统性能诊断失败: " + e.getMessage());
            result.addRecommendation("检查系统监控配置");
            log.error("系统性能诊断失败", e);
        }
        
        return result;
    }

    /**
     * 计算整体健康评分
     */
    private double calculateOverallHealthScore(DiagnosticReport report) {
        double totalScore = 0.0;
        int componentCount = 0;
        
        for (DiagnosticResult result : report.getResults().values()) {
            totalScore += result.getStatus().getHealthScore();
            componentCount++;
        }
        
        return componentCount > 0 ? totalScore / componentCount : 0.0;
    }

    /**
     * 生成故障排查建议
     */
    public TroubleshootingGuide generateTroubleshootingGuide(String problemDescription) {
        TroubleshootingGuide guide = new TroubleshootingGuide();
        guide.setProblemDescription(problemDescription);
        guide.setGeneratedAt(LocalDateTime.now());
        
        // 基于问题描述生成排查步骤
        List<TroubleshootingStep> steps = generateTroubleshootingSteps(problemDescription);
        guide.setSteps(steps);
        
        return guide;
    }

    /**
     * 生成故障排查步骤
     */
    private List<TroubleshootingStep> generateTroubleshootingSteps(String problemDescription) {
        List<TroubleshootingStep> steps = new ArrayList<>();
        String lowerProblem = problemDescription.toLowerCase();
        
        if (lowerProblem.contains("服务") && lowerProblem.contains("不可用")) {
            steps.add(new TroubleshootingStep(1, "检查服务注册状态", 
                    "查看服务是否正确注册到服务发现系统"));
            steps.add(new TroubleshootingStep(2, "检查服务健康状态", 
                    "执行健康检查，确认服务是否正常运行"));
            steps.add(new TroubleshootingStep(3, "检查网络连接", 
                    "确认服务实例之间的网络连通性"));
            steps.add(new TroubleshootingStep(4, "查看服务日志", 
                    "检查服务日志中的错误信息"));
        } else if (lowerProblem.contains("性能") && lowerProblem.contains("慢")) {
            steps.add(new TroubleshootingStep(1, "检查系统资源使用", 
                    "查看CPU、内存、磁盘使用情况"));
            steps.add(new TroubleshootingStep(2, "分析响应时间", 
                    "检查各服务的响应时间指标"));
            steps.add(new TroubleshootingStep(3, "检查数据库性能", 
                    "查看数据库查询性能和连接池状态"));
            steps.add(new TroubleshootingStep(4, "分析网络延迟", 
                    "检查网络延迟和带宽使用情况"));
        } else if (lowerProblem.contains("告警") && lowerProblem.contains("过多")) {
            steps.add(new TroubleshootingStep(1, "分析告警规则", 
                    "检查告警规则配置是否合理"));
            steps.add(new TroubleshootingStep(2, "查看告警趋势", 
                    "分析告警的时间分布和趋势"));
            steps.add(new TroubleshootingStep(3, "检查根本原因", 
                    "找出导致大量告警的根本原因"));
            steps.add(new TroubleshootingStep(4, "优化告警策略", 
                    "调整告警阈值和抑制规则"));
        } else {
            // 通用故障排查步骤
            steps.add(new TroubleshootingStep(1, "收集问题信息", 
                    "详细记录问题现象和发生时间"));
            steps.add(new TroubleshootingStep(2, "检查系统状态", 
                    "查看系统整体健康状况"));
            steps.add(new TroubleshootingStep(3, "分析相关日志", 
                    "检查相关组件的日志信息"));
            steps.add(new TroubleshootingStep(4, "验证修复效果", 
                    "确认问题是否已解决"));
        }
        
        return steps;
    }

    // ==================== 数据传输对象 ====================

    public static class DiagnosticReport {
        private LocalDateTime diagnosisTime;
        private Map<String, DiagnosticResult> results = new HashMap<>();
        private double overallHealthScore;

        // Getters and Setters
        public LocalDateTime getDiagnosisTime() { return diagnosisTime; }
        public void setDiagnosisTime(LocalDateTime diagnosisTime) { this.diagnosisTime = diagnosisTime; }
        
        public Map<String, DiagnosticResult> getResults() { return results; }
        public void setResults(Map<String, DiagnosticResult> results) { this.results = results; }
        
        public double getOverallHealthScore() { return overallHealthScore; }
        public void setOverallHealthScore(double overallHealthScore) { this.overallHealthScore = overallHealthScore; }
        
        public void addResult(String component, DiagnosticResult result) {
            this.results.put(component, result);
        }
    }

    public static class DiagnosticResult {
        private String componentName;
        private HealthStatus status;
        private Map<String, Object> metrics = new HashMap<>();
        private List<String> issues = new ArrayList<>();
        private List<String> recommendations = new ArrayList<>();

        // Getters and Setters
        public String getComponentName() { return componentName; }
        public void setComponentName(String componentName) { this.componentName = componentName; }
        
        public HealthStatus getStatus() { return status; }
        public void setStatus(HealthStatus status) { this.status = status; }
        
        public Map<String, Object> getMetrics() { return metrics; }
        public void setMetrics(Map<String, Object> metrics) { this.metrics = metrics; }
        
        public List<String> getIssues() { return issues; }
        public void setIssues(List<String> issues) { this.issues = issues; }
        
        public List<String> getRecommendations() { return recommendations; }
        public void setRecommendations(List<String> recommendations) { this.recommendations = recommendations; }
        
        public void addMetric(String key, Object value) {
            this.metrics.put(key, value);
        }
        
        public void addIssue(String issue) {
            this.issues.add(issue);
        }
        
        public void addRecommendation(String recommendation) {
            this.recommendations.add(recommendation);
        }
    }

    public static class TroubleshootingGuide {
        private String problemDescription;
        private LocalDateTime generatedAt;
        private List<TroubleshootingStep> steps;

        // Getters and Setters
        public String getProblemDescription() { return problemDescription; }
        public void setProblemDescription(String problemDescription) { this.problemDescription = problemDescription; }
        
        public LocalDateTime getGeneratedAt() { return generatedAt; }
        public void setGeneratedAt(LocalDateTime generatedAt) { this.generatedAt = generatedAt; }
        
        public List<TroubleshootingStep> getSteps() { return steps; }
        public void setSteps(List<TroubleshootingStep> steps) { this.steps = steps; }
    }

    public static class TroubleshootingStep {
        private int stepNumber;
        private String title;
        private String description;

        public TroubleshootingStep(int stepNumber, String title, String description) {
            this.stepNumber = stepNumber;
            this.title = title;
            this.description = description;
        }

        // Getters and Setters
        public int getStepNumber() { return stepNumber; }
        public void setStepNumber(int stepNumber) { this.stepNumber = stepNumber; }
        
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }
}